import { Scene } from '@babylonjs/core/scene';
import { AbstractGroup, IAbstractGroupOptions } from './abstract-group';
import { IUICheckboxOptions, UICheckbox } from './ui-checkbox';
import { IHandle } from '../../data/data-handle';
import { Utils } from '../../tool/utils';


/**
 * 复选框组参数对象
 * @param checkedValue 选中的选项
 * @param revocable 是否可清空
 */
interface IUICheckboxGroupOptions extends IAbstractGroupOptions<IUICheckboxOptions> {
    checkedValue?: string[],
    revocable?: boolean
}


/**
 * 复选框组控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 */
class UICheckboxGroup extends AbstractGroup {

    private _checkedValue: string[] = [];
    private _revocable!: boolean;

    constructor(name: string, scene: Scene, options?: IUICheckboxGroupOptions) {
        super(name, scene, options);
        const ops = options || {};
        this.checkedValue = ops.checkedValue || [];
    }

    /**
     * 设置选中的选项
     */
    public set checkedValue(values: string[]) {
        if (values.length === 0) {
            if (!this._revocable) return;
        }
        const vs = Utils.noDuplication(values);
        for (const item of this.items) {
            (item as UICheckbox).isChecked = vs.includes(item.key);
        }
    }

    /**
     * 获取选中的选项
     */
    public get checkedValue(): string[] {
        return [...this._checkedValue];
    }

    public onChange(func: (value: string[]) => void): IHandle<string[]> {
        return super.onChange(func);
    }

    protected generateItem(name: string, scene: Scene, itemOptions: IUICheckboxOptions, groupOptions: IUICheckboxGroupOptions): UICheckbox {

        this._revocable = groupOptions.revocable === undefined ? true : groupOptions.revocable;
        const checkbox = new UICheckbox(name, scene, itemOptions);

        checkbox.onChange((isChecked: boolean) => {
            const value = checkbox.key;
            if (isChecked) {
                if (this._checkedValue.includes(value)) return;
                this._checkedValue.push(value);
            } else {
                const idx = this._checkedValue.indexOf(value);
                if (idx < 0) return;
                if (this.checkedValue.length === 1) {
                    checkbox.isChecked = true;
                    if (!this._revocable) return;
                }
                this._checkedValue.splice(idx, 1);
            }
            if (!this.avoidEventHandle) this.changeHandles.forEach(handle => handle.callback([...this._checkedValue]));
        });
        return checkbox;
    }

}


/**
 * 创建复选框组控件
 * @param name 名称
 * @param scene 所在的场景
 * @param options 参数对象
 * @param changeCallback 值改变时的回调函数
 * @returns 复选框组控件
 */
const CreateUICheckboxGroup = (name: string, scene: Scene, options?: IUICheckboxGroupOptions, changeCallback?: { (values: Array<string>): void }): UICheckboxGroup => {
    const group = new UICheckboxGroup(name, scene, options);
    if (changeCallback) group.onChange(changeCallback);
    return group;
};


export { UICheckboxGroup, CreateUICheckboxGroup };
export type { IUICheckboxGroupOptions };